import { Flex, StepperField } from '@aws-amplify/ui-react';

import { StepperFieldDemo } from './demo';
import {
  ControlledStepperFieldExample,
  DefaultStepperFieldExample,
  DisabledStepperFieldExample,
  ReadOnlyStepperFieldExample,
  StepperFieldAccessibilityExample,
  StepperFieldSizeExample,
  StepperFieldValidationErrorExample,
  StepperFieldThemeExample,
  StepperFieldStylePropsExample,
} from './examples';
import { Example, ExampleCode } from '@/components/Example';
import { Fragment } from '@/components/Fragment';
import { ComponentClassTable } from '@/components/ComponentClassTable';
import StandardHTMLAttributes from '@/components/StandardHTMLAttributes.mdx';
import { ComponentStyleDisplay } from '@/components/ComponentStyleDisplay';
import ThemeExample from '@/components/ThemeExample.mdx';

## Demo

<StepperFieldDemo />

## Usage

Import StepperField and styles. You could edit the stepping value directly but it will be validated and rounded to a valid one when the field loses focus.

<Example>
  <DefaultStepperFieldExample />

  <ExampleCode>
    ```jsx file=./examples/DefaultStepperFieldExample.tsx

    ```

  </ExampleCode>
</Example>

### Controlled component

To use the StepperField as a controlled component, use the `value` prop and `onStepChange` handler.

Note that `onStepChange` returns a new value (`number`), not the event object. This is because the StepperField is a complex component which is handling input, blur, and change events on the input element as well as click events on the button elements. The `onStepChange` handler simplifies all of this and returns the new value of the input in response to any of these events.

<Example>
  <ControlledStepperFieldExample />
  <ExampleCode>
    ```tsx file=./examples/ControlledStepperFieldExample.tsx

    ```

  </ExampleCode>
</Example>

### Accessibility / Label behavior

<Fragment>{() => import('./../shared/formFieldAccessibility.mdx')}</Fragment>

<Example>
  <StepperFieldAccessibilityExample />
  <ExampleCode>
    ```jsx file=./examples/StepperFieldAccessibilityExample.tsx

    ```

  </ExampleCode>
</Example>

### Sizes

Use the `size` prop to change the StepperField size. Available options are `small`, `large`, and none (default).

<Example>
  <StepperFieldSizeExample />
  <ExampleCode>
    ```jsx file=./examples/StepperFieldSizeExample.tsx

    ```

  </ExampleCode>
</Example>

### State

The available StepperField states include `isDisabled` and `isReadOnly`. A disabled field will not be focusable or mutable and will not be submitted with form data. A read-only field cannot be edited by the user.

#### Disabled StepperField

<Example>
  <DisabledStepperFieldExample />
  <ExampleCode>
    ```jsx file=./examples/DisabledStepperFieldExample.tsx

    ```

  </ExampleCode>
</Example>

#### Read-only StepperField

<Example>
  <ReadOnlyStepperFieldExample />
  <ExampleCode>
    ```jsx file=./examples/ReadOnlyStepperFieldExample.tsx

    ```

  </ExampleCode>
</Example>

### Validation error

Use the `hasError` and `errorMessage` props to mark a StepperField as having an validation error.

<Example>
  <StepperFieldValidationErrorExample />
    <ExampleCode>
    ```jsx file=./examples/StepperFieldValidationErrorExample.tsx

    ```

  </ExampleCode>
</Example>

<StandardHTMLAttributes component="StepperField" link="input" element="<input>">
  <Example>
    <StepperField
      label="Stepper"
      min={0}
      max={10}
      step={1}
      name="stepper"
    />

    <ExampleCode>

    ```jsx
    <StepperField
      label="Stepper"
      min={0}
      max={10}
      step={1}
      name="stepper"
    />
    ```

    </ExampleCode>

  </Example>
</StandardHTMLAttributes>

## CSS Styling

<ThemeExample component="StepperField">
  <Example>
    <StepperFieldThemeExample />
    
    <ExampleCode>

    ```tsx file=./examples/StepperFieldThemeExample.tsx

    ```

    </ExampleCode>
  </Example>
</ThemeExample>

### Target classes

<ComponentStyleDisplay componentName="StepperField" />

### Global styling

To override styling on all StepperFields, you can set the Amplify CSS variables or use the built-in `.amplify-stepperfield`, `.amplify-stepperfield__input`, `amplify-stepperfield__button--decrease` and `amplify-stepperfield__button--increase` class.

<Example>
  <StepperField
    label="Stepper"
    className="global-styling-example"
    defaultValue={0}
    min={0}
    max={10}
    step={1}
    labelHidden
  />

  <ExampleCode>
    ```css
    /* styles.css */
    :root {
      --amplify-components-stepperfield-input-border-color: var(
        --amplify-colors-purple-80
      );
    }
    /* OR */
    .amplify-stepperfield__input {
      border-color: var(--amplify-colors-purple-80);
    }
    ```
  </ExampleCode>
</Example>

### Local styling

To override styling on a specific StepperField, you can use (in order of increasing specificity): a class selector, data attributes, or style props.

_Using a class selector:_

<Example>
  <StepperField
    label="Stepper"
    className="custom-button"
    defaultValue={0}
    min={0}
    max={10}
    step={1}
    labelHidden
  />
  <ExampleCode>
    ```css
    /* styles.css */
    .custom-button .amplify-stepperfield__button--decrease,
    .amplify-stepperfield__button--increase {
      color: var(--amplify-colors-white);
      background-color: var(--amplify-colors-purple-80);
    }
    ```
  </ExampleCode>
  <ExampleCode>
    ```jsx
    import { StepperField } from '@aws-amplify/ui-react';

    import './styles.css';

    <StepperField
      label="Stepper"
      classname="custom-button"
      defaultValue={0}
      min={0}
      max={10}
      step={1}
      labelHidden
    />;
    ```

  </ExampleCode>
</Example>

_Using data attributes:_

<Example>
  <StepperField
    label="Stepper"
    className="data-attribute-large-size"
    defaultValue={0}
    min={0}
    max={10}
    size="large"
    step={1}
    labelHidden
  />
  <ExampleCode>
    ```css
    /* styles.css */

    /* Override only large size styles */
    .amplify-stepperfield[data-size='large'] {
      width: 50%;
    }
    ```

  </ExampleCode>
</Example>

_Using style props:_

All style props will be applied to the [`Flex`](flex) wrapper of the `StepperField`. To style the `input` of the `StepperField`, you can pass a `inputStyles` prop with the style props you want to apply to the input.

<Example>
  <StepperFieldStylePropsExample />
  
  <ExampleCode>
    ```jsx file=./examples/StepperFieldStylePropsExample.tsx
    ```

  </ExampleCode>
</Example>